package com.sinotn.ks.node.camera.job;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;

import com.sinotn.SinotnLogger;
import com.sinotn.gson.GsonFacade;
import com.sinotn.ks.definition.ExamEngine;
import com.sinotn.ks.definition.MngComputer;
import com.sinotn.ks.definition.TcpToken;
import com.sinotn.ks.netty.message.SimpleMessage;
import com.sinotn.ks.node.camera.ImageAnalyser;
import com.sinotn.ks.node.camera.dao.cond.CameraPhotoCond;
import com.sinotn.ks.node.camera.service.CameraService;
import com.sinotn.ks.node.camera.vo.CameraPhotoVO;

/**
 * 
 * @Title CameraPhotoBaiduCheckTask.java
 * @Package com.sinotn.ks.node.camera.job
 * @Description 
 * Copyright: Copyright (c) 2022
 * Company:广东峰上科技有限公司
 * 
 * @author <a href="mailto:xieqj@fstec.com">谢启进</a>
 * @date 2022年4月21日 下午7:35:27
 * @version V1.0
 */
public class CameraPhotoBaiduCheckTask {
	@Autowired
	private CameraService cameraService;
	@Autowired
	private ExamEngine examEngine;
	@Autowired
	private ImageAnalyser imageAnalyser;
	@Autowired
	private TcpToken tcpToken;

	public volatile int errCount = 0;

	/**
	 * cron表达式：* * * * * *（共6位，使用空格隔开，具体如下）
	 * cron表达式：*(秒0-59) *(分钟0-59) *(小时0-23)
	 * (日期1-31) *(月份1-12或是JAN-DEC) *(星期1-7或是SUN-SAT)
	 */
	public void photoProcessStart() {
		if(this.examEngine.getRunState()!=ExamEngine.STATE_STD) return;
		try {
			// 照片比对
			if(this.examEngine.getExamineeSize()>0){
				CameraPhotoCond cond = new CameraPhotoCond();
				cond.setState((byte) 0);
				cond.setFixed((byte) 0);
				List<CameraPhotoVO> list=this.cameraService.findCameraPhotos(1, 500, cond);
				if(!list.isEmpty()){
					int size=list.size();
					for(int i=0;i<size;i++){
						imageAnalyser.analyse(list.get(i));
					}
				}
				// 发送消息给管理机
				List<MngComputer> manageComputers=examEngine.allManageComputer();
				if(manageComputers!=null){
					MngComputer mngComputer; 
					List<String> roomIds;
					int j;
					int idSize;
					String roomId;
					ComputerContext computerCtx;
					RoomContext roomCtx;
					HashMap<String, RoomContext> roomCtxs=new HashMap<String, CameraPhotoBaiduCheckTask.RoomContext>();
					int size=manageComputers.size();
					ArrayList<ComputerContext> computerCtxs=new ArrayList<CameraPhotoBaiduCheckTask.ComputerContext>(size);
					for(int i=0;i<size;i++){
						mngComputer=manageComputers.get(i);
						roomIds=mngComputer.getRoomIds();
						if(roomIds==null) continue;
						computerCtx=new ComputerContext();
						computerCtx.computer=mngComputer;
						computerCtxs.add(computerCtx);
						idSize=roomIds.size();
						for(j=0;j<idSize;j++){
							roomId=roomIds.get(j);
							roomCtx=roomCtxs.get(roomId);
							if(roomCtx==null){
								roomCtx=new RoomContext();
								roomCtx.id=roomId;
								roomCtxs.put(roomId, roomCtx);
							}
							roomCtx.addComputerCtx(computerCtx);
						}
					}
					if(!roomCtxs.isEmpty()){
						int warnCount;
						for(Iterator<RoomContext> it=roomCtxs.values().iterator();it.hasNext();){
							roomCtx=it.next();
							warnCount=this.cameraService.getWarnPhotoCount(roomCtx.id);
							roomCtx.incWarnCount(warnCount);
						}
						long token=this.tcpToken.nextToken();
						SimpleMessage sm;
						HashMap<String, Object> body;
						size=computerCtxs.size();
						for(j=0;j<size;j++){
							computerCtx=computerCtxs.get(j);
							sm = new SimpleMessage(104, token);
							body = new HashMap<String, Object>();
							body.put("method", "camera#warning");
							body.put("text", computerCtx.warnCount);
							sm.setText(GsonFacade.toJson(body));
							computerCtx.computer.sendMessage(sm);
						}
					}
				}
			}
			
			this.errCount=0;
		} catch (RuntimeException e) {
			errCount++;
			if (errCount <= 5) {
				SinotnLogger.DEBUG.error("执行照片对比时发生错误：", e);
			}
		}
	}
	
	class RoomContext{
		List<ComputerContext> computerCtxs;
		String id;
		public void addComputerCtx(ComputerContext computerCtx) {
			if(computerCtxs==null){
				computerCtxs=new ArrayList<CameraPhotoBaiduCheckTask.ComputerContext>(2);
			}
			computerCtxs.add(computerCtx);
		}
		public void incWarnCount(int warnCount) {
			int size=this.computerCtxs.size();
			for(int i=0;i<size;i++){
				this.computerCtxs.get(i).inc(warnCount);
			}
		}
	}
	
	class ComputerContext{
		MngComputer computer;
		int warnCount;
		
		public void inc(int count) {
			this.warnCount+=count;
		}
	}
}
